﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.IO;
using System.Xml.Serialization;

namespace MatthiWare.PortChecker.UI
{
    

    public partial class SettingsDialog : Form
    {
        private const string SETTINGS_PATH = @".\settings.xml";
        public SettingsDialog()
        {
            InitializeComponent();

            if (File.Exists(SETTINGS_PATH))
            {
                IP_SETTINGS_FILE settings;
                if (!LoadSetting(out settings))
                {
                    File.Delete(SETTINGS_PATH);
                    txtIp.Text = "127.0.0.1";
                    MessageBox.Show("The settings file got corrupted, a new one will be generated on the next save!", "Settings file error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
                else
                    txtIp.Text = settings.IP;
            }

        }

        private void btnOk_Click(object sender, EventArgs e)
        {
            IPAddress ip;
            String strIp = txtIp.Text;

            if (IPAddress.TryParse(strIp, out ip))
            {
                    Save(strIp);

                MessageBox.Show("Settings saved!");
                this.Close();
            }
            else
                MessageBox.Show("Invalid IPv4");
        }

        private void Save(string strip) 
        {
            for (int i = 0; i < 4; i++)
            {
                try
                {
                    XmlSerializer xmlSerializer = new XmlSerializer(typeof(IP_SETTINGS_FILE));
                    IP_SETTINGS_FILE setting = new IP_SETTINGS_FILE(strip);
                    FileStream fs = null;

                    if (File.Exists(SETTINGS_PATH))
                        fs = File.Open(SETTINGS_PATH, FileMode.Open, FileAccess.Write);
                    else
                        fs = File.Open(SETTINGS_PATH, FileMode.Create, FileAccess.Write);

                    xmlSerializer.Serialize(fs, setting);
                    if (fs != null)
                    {
                        fs.Dispose();
                        fs = null;
                    }

                    if (LoadSetting(out setting))
                        return;
                }
                catch (Exception)
                {

                    i++;
                }
            }
        }

        public bool LoadSetting(out IP_SETTINGS_FILE settings)
        {
            FileStream fs = null;
            settings = new IP_SETTINGS_FILE();
            try
            {
                fs= File.Open(SETTINGS_PATH, FileMode.Open, FileAccess.Read);
                XmlSerializer xmlSerializer = new XmlSerializer(typeof(IP_SETTINGS_FILE));
                settings = (IP_SETTINGS_FILE)xmlSerializer.Deserialize(fs);
                txtIp.Text = settings.IP;
            }
            catch (Exception e)
            {
                if (fs != null)
                {
                    fs.Close();
                    fs = null;
                }

                File.Delete(SETTINGS_PATH);
                Console.WriteLine(e.Message + "\n" + e.StackTrace);

                return false;
            }
            finally
            {
                if (fs != null)
                {
                    fs.Close();
                    fs = null;
                }
            }

            return true;
        }

        private string GetPublicIpFromIfConfig()
        {


            string publicIPAddress = "-1";

            try
            {
                var request = (HttpWebRequest)WebRequest.Create("http://ifconfig.me/ip");
                request.UserAgent = "curl";
                request.Method = "GET";

                using (WebResponse response = request.GetResponse())
                {
                    using (var reader = new StreamReader(response.GetResponseStream()))
                    {
                        publicIPAddress = reader.ReadToEnd();
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }

            return publicIPAddress.Replace("\n", "");
        }

        private string GetPublicIPFromDynDns()
        {
            string ip = "-1";
            WebRequest req;

            try
            {
                string url = "http://checkip.dyndns.org";
                req = WebRequest.Create(url);

                using (WebResponse resp = req.GetResponse())
                {
                    using (StreamReader sr = new StreamReader(resp.GetResponseStream()))
                    {
                        string response = sr.ReadToEnd().Trim();
                        string[] a = response.Split(':');
                        string a2 = a[1].Substring(1);
                        string[] a3 = a2.Split('<');
                        string a4 = a3[0];
                        ip = a4;
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }

            return ip;
        }

        private void btnExternal_Click(object sender, EventArgs e)
        {
            String dynDns = GetPublicIPFromDynDns();
            String ifConfig = "";

            IPAddress ip;

            bool suc1 = IPAddress.TryParse(dynDns, out ip);

            if (!suc1)
            {
                ifConfig = GetPublicIpFromIfConfig();
                bool suc2 = IPAddress.TryParse(ifConfig, out ip);

                if (suc2)
                {
                    txtIp.Text = ifConfig;
                    return;
                }
                else
                {
                    txtIp.Text = "127.0.0.1";
                    MessageBox.Show("Unable to find extern/public IP", "IP Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
            }
            else
            {
                txtIp.Text = dynDns;
                return;
            }
        }

        private void btnDefault_Click(object sender, EventArgs e)
        {
            txtIp.Text = "127.0.0.1";
        }

        public IPAddress GetNewIp()
        {
            IPAddress ip = IPAddress.Loopback;
            String strIp = txtIp.Text;
            bool succes = IPAddress.TryParse(strIp, out ip);

            if (succes)
                return ip;
            else
                return IPAddress.Loopback;
        }

        public String GetStrIp()
        {
            return txtIp.Text;
        }

        private void btnDnsResolver_Click(object sender, EventArgs e)
        {
            DnsResolverDialong dnsDialog = new DnsResolverDialong();
            dnsDialog.ShowDialog(this);
        }
    }
}
